Skip to content

Make rewards-delegated-vrf and anchor-rock-paper-scissor work with SDK 'backward-compat` flag#82

Open
snawaz wants to merge 17 commits into
mainfrom
snawaz/sdk-backward-compat
Open

Make rewards-delegated-vrf and anchor-rock-paper-scissor work with SDK 'backward-compat` flag#82
snawaz wants to merge 17 commits into
mainfrom
snawaz/sdk-backward-compat

Conversation

@snawaz
Copy link
Copy Markdown
Contributor

@snawaz snawaz commented May 9, 2026

  • The reviewable changes are mostly in Cargo.toml files,
  • Two new programs have been added (copied and upgraded for Anchor 1.0, 2)
    • rewards-delegated-vrf-1.0 now contains a vendored ephemeral-vrf-sdk at rewards-delegated-vrf-1.0/vendor/ephemeral-vrf-sdk.
    • That implies, we also need to upgrade it in a similar way.
  • Updated Rust version in the CI.

Summary by CodeRabbit

  • New Features
    • Full rewards system: VRF-based random requests/consumption, SPL token & programmable NFT rewards, reward CRUD, delegation/undelegation, admin & whitelist management, and automated transfer flows.
    • On-chain Rock‑Paper‑Scissors game: create/join/play/reveal, permission management, and delegation flows.
  • Documentation
    • New READMEs, Anchor/toolchain configs, and project scripts for setup, build, and testing.
  • Tests
    • Comprehensive integration tests, fixtures, and test helpers.
  • Chores
    • Workspace/tooling updates, ignore rules, and vendored SDK changes for local development.

Review Change Stack

@vercel
Copy link
Copy Markdown

vercel Bot commented May 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
er-rolldice Ready Ready Preview, Comment May 19, 2026 4:16pm
magicblock-counter-example Ready Ready Preview, Comment May 19, 2026 4:16pm
magicblock-engine-examples Ready Ready Preview, Comment May 19, 2026 4:16pm
magicblock-rewards-dashboard Ready Ready Preview, Comment May 19, 2026 4:16pm
spl-tokens Ready Ready Preview, Comment May 19, 2026 4:16pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a new rewards-delegated-vrf Anchor program with state, instruction handlers, vendored ephemeral-vrf SDK and proc-macro, tests/helpers/fixtures, workspace/tooling files, example rock-paper-scissor, and switches ephemeral-rollups-sdk usages to local path with adjusted features.

Changes

Rewards Delegated VRF + workspace + SDK

Layer / File(s) Summary
Workspace & tooling configs
rewards-delegated-vrf-1.0/*, anchor-rock-paper-scissor-1.0/*, .github/workflows/test-examples.yml
Adds Cargo workspace manifests, Anchor.toml files, rust-toolchain pins, tsconfig/package.json, READMEs, .gitignore/.prettierignore, and updates GitHub Actions Rust to 1.93.1.
Vendored ephemeral-vrf SDK & macro
rewards-delegated-vrf-1.0/vendor/ephemeral-vrf-sdk/*
Adds vendored VRF SDK crate with consts, PDA helpers, rnd/types, request-instruction builder, library root, optional Anchor glue, and a procedural macro crate for VRF helper.
Program contracts & types
rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/{state,constants,errors}
Defines on-chain structs (RewardDistributor, RewardsList, Reward, TransferLookupTable), RewardType enum, PDA seed constants, REWARD_LIST_SPACE, and RewardError variants.
Helpers & validation
rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/helpers.rs
Implements reward-type detection, per-reward/list validation, inventory math, and duplicate-pubkey utilities.
Core instructions
rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/instructions/*
Adds handlers for add/update/remove rewards, request/consume randomness, delegate/undelegate, set_reward_list/admins/whitelist, initialize distributor/lookup table, and module exports.
Transfer actions & shared helper
.../instructions/shared.rs, transfer_reward_spl_token.rs, transfer_reward_programmable_nft.rs
Adds execute_reward_transfer helper and CPIs for SPL and programmable NFT transfers using magic intent bundles and CPL/Metaplex CPIs.
Tests, helpers & fixtures
rewards-delegated-vrf-1.0/tests/*
Adds extensive integration tests, helpers, PDAs utility, constants, fixtures (NFT metadata/mints/user keypair), and test setup utilities.
Rock-Paper-Scissors example
anchor-rock-paper-scissor-1.0/..., anchor-rock-paper-scissor/programs/anchor-rock-paper-scissor/*
Adds example Anchor program, tests, docs, and workspace entries integrating ephemeral-rollups-sdk (local path).
Cargo dependency edits
multiple Cargo.toml files
Switches several crates to use a local ephemeral-rollups-sdk path and updates features to anchor-compat or updated versions.

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • GabrielePicco
  • jonasXchen
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch snawaz/sdk-backward-compat

@snawaz snawaz requested a review from jonasXchen May 9, 2026 10:28
Copy link
Copy Markdown
Contributor Author

snawaz commented May 9, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@anchor-rock-paper-scissor/programs/anchor-rock-paper-scissor/Cargo.toml`:
- Line 24: The Cargo.toml entry for the dependency named ephemeral-rollups-sdk
currently uses a machine-specific absolute path; replace this with a portable
solution by removing the path attribute and either specifying a published
version (e.g., ephemeral-rollups-sdk = "x.y.z" with the required features) or
revert to a local override via a project-level .cargo/config.toml
[patch.crates-io] override; update the dependency declaration in
anchor-rock-paper-scissor's Cargo.toml (and the same dependency in
rewards-delegated-vrf's Cargo.toml) so CI and other developers do not rely on an
absolute filesystem path.

In `@rewards-delegated-vrf/programs/rewards-delegated-vrf/Cargo.toml`:
- Line 24: The Cargo.toml currently pins ephemeral-rollups-sdk to a local
absolute path (ephemeral-rollups-sdk = { path = "/Users/..."}), which breaks CI;
change that dependency to a portable reference by replacing the path entry for
ephemeral-rollups-sdk with either a published crate version (e.g.,
ephemeral-rollups-sdk = "x.y.z") or a git-based reference (e.g.,
ephemeral-rollups-sdk = { git = "https://...", tag = "vX.Y.Z" }) and preserve
any needed features like ["anchor","backward-compat"]; make the same change in
the other occurrence for anchor-rock-paper-scissor so both Cargo.toml files use
a portable version/git dependency instead of the local path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 348db2ce-a225-4e7c-8b3c-edf16195a680

📥 Commits

Reviewing files that changed from the base of the PR and between 3d91320 and 0a9ddcd.

⛔ Files ignored due to path filters (1)
  • anchor-rock-paper-scissor/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • anchor-rock-paper-scissor/programs/anchor-rock-paper-scissor/Cargo.toml
  • rewards-delegated-vrf/programs/rewards-delegated-vrf/Cargo.toml

Comment thread anchor-rock-paper-scissor/programs/anchor-rock-paper-scissor/Cargo.toml Outdated
Comment thread rewards-delegated-vrf/programs/rewards-delegated-vrf/Cargo.toml Outdated
@snawaz snawaz requested a review from GabrielePicco May 13, 2026 03:50
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/instructions/consume_random_reward.rs (1)

66-77: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Guard reward.reward_mints before modulo/index access.

If reward_mints is empty, this path panics: line 73 attempts % 0 (modulo by zero) and line 76 attempts [0] (index out of bounds), aborting the instruction.

Suggested fix
                     if !transfer_lookup_table.lookup_accounts.is_empty() {
+                        require!(
+                            !reward.reward_mints.is_empty(),
+                            crate::errors::RewardError::InsufficientRewardMints
+                        );
                         let reward_type = reward.reward_type.clone();
                         let mint = match reward_type {

Note: InvalidRewardConfiguration does not exist in the errors enum. Use InsufficientRewardMints or define a new error type.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/instructions/consume_random_reward.rs`
around lines 66 - 77, The code currently assumes reward.reward_mints is
non-empty and will panic on modulo by zero or indexing; in the
consume_random_reward logic guard reward.reward_mints.is_empty() up front and
return the existing InsufficientRewardMints error (or add that variant) instead
of proceeding. Ensure both branches that compute mint_index (using
ephemeral_vrf_sdk::rnd::random_u32 and rotate logic) and the fallback that
accesses reward.reward_mints[0] are only executed when reward.reward_mints.len()
> 0, and replace any reference to a non-existent InvalidRewardConfiguration with
InsufficientRewardMints.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@magic-actions/programs/magic-actions/Cargo.toml`:
- Around line 24-25: Replace the machine-local absolute path for the
ephemeral-rollups-sdk dependency in Cargo.toml with a portable versioned
dependency; remove the path-based entry `ephemeral-rollups-sdk = { path = "...",
features = ["anchor-compat"] }` and instead declare a published version (e.g.,
`ephemeral-rollups-sdk = { version = "0.13.0", features = ["anchor-compat"] }`)
or the previously working version for this project so CI and other developer
machines can resolve the crate.

In `@rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/Cargo.toml`:
- Around line 25-27: Replace the machine-local absolute paths in Cargo.toml for
the ephemeral-rollups-sdk and ephemeral-vrf-sdk dependencies with portable
sources: either the relative vendor paths (e.g., use the existing vendor
directory) or published crate versions; update the entries referencing
ephemeral-rollups-sdk and ephemeral-vrf-sdk to point to the relative path inside
the repo (or a semver on crates.io) instead of "/Users/…", and remove or restore
the commented vendor line if it was the intended portable path so builds work on
other machines and CI.

In
`@rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/instructions/consume_random_reward.rs`:
- Around line 31-34: Replace the unchecked unwrap on the subtraction with a
proper error return using an existing RewardError variant: compute the delta
with reward_list.global_range_max as u64
.checked_sub(reward_list.global_range_min as
u64).ok_or(RewardError::RewardRangeExceedsGlobalBounds)? then set range = delta
+ 1; this ensures consume_random_reward.rs returns a typed error
(RewardRangeExceedsGlobalBounds) instead of panicking when min > max.

---

Duplicate comments:
In
`@rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/instructions/consume_random_reward.rs`:
- Around line 66-77: The code currently assumes reward.reward_mints is non-empty
and will panic on modulo by zero or indexing; in the consume_random_reward logic
guard reward.reward_mints.is_empty() up front and return the existing
InsufficientRewardMints error (or add that variant) instead of proceeding.
Ensure both branches that compute mint_index (using
ephemeral_vrf_sdk::rnd::random_u32 and rotate logic) and the fallback that
accesses reward.reward_mints[0] are only executed when reward.reward_mints.len()
> 0, and replace any reference to a non-existent InvalidRewardConfiguration with
InsufficientRewardMints.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: bdaba350-ead3-4499-ac2b-d4b13c7f18cf

📥 Commits

Reviewing files that changed from the base of the PR and between 52353e3 and d48f86f.

⛔ Files ignored due to path filters (6)
  • anchor-counter/Cargo.lock is excluded by !**/*.lock
  • anchor-rock-paper-scissor-1.0/Cargo.lock is excluded by !**/*.lock
  • anchor-rock-paper-scissor/Cargo.lock is excluded by !**/*.lock
  • magic-actions/Cargo.lock is excluded by !**/*.lock
  • rewards-delegated-vrf-1.0/Cargo.lock is excluded by !**/*.lock
  • rewards-delegated-vrf/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • .github/workflows/test-examples.yml
  • anchor-counter/programs/public-counter/Cargo.toml
  • anchor-rock-paper-scissor-1.0/programs/anchor-rock-paper-scissor/Cargo.toml
  • anchor-rock-paper-scissor-1.0/programs/anchor-rock-paper-scissor/src/lib.rs
  • anchor-rock-paper-scissor/programs/anchor-rock-paper-scissor/Cargo.toml
  • magic-actions/programs/magic-actions/Cargo.toml
  • rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/Cargo.toml
  • rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/instructions/consume_random_reward.rs
  • rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/lib.rs
  • rewards-delegated-vrf/programs/rewards-delegated-vrf/Cargo.toml

Comment thread magic-actions/programs/magic-actions/Cargo.toml Outdated
Comment thread rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/Cargo.toml Outdated
Comment on lines +31 to +34
let range = (reward_list.global_range_max as u64)
.checked_sub(reward_list.global_range_min as u64)
.unwrap()
+ 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the target file
cd rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf && cat -n src/instructions/consume_random_reward.rs | head -50

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 2333


🏁 Script executed:

# Search for error definitions in the project
find . -name "*.rs" -type f | xargs grep -l "enum.*RewardError\|pub enum.*Error" | head -10

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 555


🏁 Script executed:

# Look for error module structure
find . -name "errors.rs" -o -name "error.rs" | head -5

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 301


🏁 Script executed:

# Check the error definitions in the targeted file
cat -n rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/errors.rs

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 4963


🏁 Script executed:

# Also check if there's error handling in the lib.rs or main module
cat -n rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/lib.rs | head -80

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 3118


Avoid unwrap() in on-chain range validation.

An invalid min/max configuration should return a typed error, not panic the program. The suggested error variant InvalidGlobalRange does not exist in the RewardError enum. Consider using an existing variant like RewardRangeExceedsGlobalBounds or add InvalidGlobalRange to the error enum first.

Suggested fix (if using existing error)
         let range = (reward_list.global_range_max as u64)
             .checked_sub(reward_list.global_range_min as u64)
-            .unwrap()
+            .ok_or(crate::errors::RewardError::RewardRangeExceedsGlobalBounds)?
             + 1;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let range = (reward_list.global_range_max as u64)
.checked_sub(reward_list.global_range_min as u64)
.unwrap()
+ 1;
let range = (reward_list.global_range_max as u64)
.checked_sub(reward_list.global_range_min as u64)
.ok_or(crate::errors::RewardError::RewardRangeExceedsGlobalBounds)?
1;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@rewards-delegated-vrf-1.0/programs/rewards-delegated-vrf/src/instructions/consume_random_reward.rs`
around lines 31 - 34, Replace the unchecked unwrap on the subtraction with a
proper error return using an existing RewardError variant: compute the delta
with reward_list.global_range_max as u64
.checked_sub(reward_list.global_range_min as
u64).ok_or(RewardError::RewardRangeExceedsGlobalBounds)? then set range = delta
+ 1; this ensures consume_random_reward.rs returns a typed error
(RewardRangeExceedsGlobalBounds) instead of panicking when min > max.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant